﻿using System;
using ImpromptuInterface.MVVM;

namespace DynamicCalc
{
    public interface ICalcViewModel
    {
        decimal LeftSideEq { get; set; }
        decimal RightSideEq { get; set; }

        string Display { get; set; }
        string LeftBuffer { get; set; }
        string RightBuffer { get; set; }
        string SymbolBuffer { get; set; }
        string LastBuffer { get; set; }
    }

    public class CalcViewModel:ImpromptuViewModel<ICalcViewModel>
    {
        public CalcViewModel()
        {
            Contract.LeftBuffer = String.Empty;
            Contract.RightBuffer = String.Empty;
            Contract.SymbolBuffer = String.Empty;

            Setup.Property.LeftBuffer.OnChange += ChangedHandler((sender, e) =>
                                                       {
                                                           Contract.Display = Contract.LeftBuffer;
                                                           Dynamic.LeftSideEq = Contract.LeftBuffer;
                                                       });
            Setup.Property.RightBuffer.OnChange += ChangedHandler((sender, e) =>
                                                        {
                                                            Contract.Display = Contract.RightBuffer;
                                                            Dynamic.RightSideEq = Contract.RightBuffer;
                                                        });
            Setup.Property.SymbolBuffer.OnChange += ChangedHandler((sender, e) => Contract.Display = Contract.SymbolBuffer);

        }


        protected decimal Calculate()
        {
            switch (Contract.SymbolBuffer)
            {
                case "+":
                    return Contract.LeftSideEq + Contract.RightSideEq;
                case "-":
                    return Contract.LeftSideEq - Contract.RightSideEq;
                case "*":
                    return Contract.LeftSideEq * Contract.RightSideEq;
                case "/":
                    return Contract.LeftSideEq / Contract.RightSideEq;
                default:
                    throw new Exception("Unknown Symbol");
            }
        }

        public void RunEquation(object dummy = null)
        {
            try
            {
                var tResult = Calculate();
                ClearAll();
                Dynamic.LastBuffer = tResult;
                if (dummy != null)
                    Contract.Display = Contract.LastBuffer;
                else
                    Contract.LeftBuffer = Contract.LastBuffer;
            }
            catch
            {
                ClearAll();
                Contract.Display = "Error";
            }
        }

        public void Number(string content)
        {
            if (String.IsNullOrWhiteSpace(Contract.SymbolBuffer))
            {
                Contract.LeftBuffer += content;
            }
            else
            {
                Contract.RightBuffer += content;
            }
        }

        public void Symbol(string content)
        {
            if (String.IsNullOrWhiteSpace(Contract.LeftBuffer))
            {
                Contract.LeftBuffer = Contract.LastBuffer;
            }

            //If equation is full run equation
            if (!String.IsNullOrWhiteSpace(Contract.RightBuffer))
            {
                RunEquation();
            }
            Contract.SymbolBuffer = String.Empty;
            Contract.SymbolBuffer = content;
        }

        public void ClearAll(object dummy = null)
        {
            //Clear All
            Contract.LeftBuffer = String.Empty;
            Contract.RightBuffer = String.Empty;
            Contract.SymbolBuffer = String.Empty;
            Contract.Display = String.Empty;
            Contract.LastBuffer = String.Empty;
        }

        public void ClearRecent(object dummy =null)
        {
            //Undo Last Part of Equation
            if (!String.IsNullOrWhiteSpace(Contract.RightBuffer)) 
            {
                Contract.RightBuffer = String.Empty;
                Contract.Display = Contract.SymbolBuffer;
            }
            else if (!String.IsNullOrWhiteSpace(Contract.SymbolBuffer))
            {
                Contract.SymbolBuffer = String.Empty;
                Contract.Display = Contract.LeftBuffer;
            }
            else
            {
                ClearAll();
            }
        }

    }

    
}
